package cn.com.callback

import cn.com.kh.KHDBConfig
import javafx.beans.binding.ListBinding
import javafx.collections.ObservableList
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.com.elite.EliteBean

import cn.com.elite.Util;
import cn.com.kh.hst.ThreeDesUtil;
import org.json.JSONObject
import org.apache.commons.io.FileUtils;

import org.apache.commons.mail.util.MimeMessageParser;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.protocol.HTTP
import org.springframework.web.multipart.MultipartFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.activation.DataSource;
import javax.activation.MimetypesFileTypeMap;
import javax.mail.Address;
import javax.mail.Session;
import javax.mail.internet.MimeMessage
import java.text.SimpleDateFormat;
import java.time.Instant
import cn.com.kh.getProperty;
import cn.com.kh.HttpClientUtil;

/**
 *
 * @Title: autoHSTEmailSendTask
 * @Description:华盛证券 邮件api发送  --  内部接口。
 * @author: chieh
 * @date 2023-02-02 12:00:00
 *
 */

public class autoHSTEmailSendTask implements CallBackInvoke{
	private static final Logger log = LoggerFactory.getLogger(autoHSTEmailSendTask.class);

	private static String CM_ProductToken = "b4b49728-9eda-4f10-980e-da21ac4372b7";
	private static SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public void doCallBack(EliteBean eliteBean, String callBack, Map map, String paramString) {

		//测试  /home/www/data/ngsfiles
		//生产  /nfs/ngsfiles
		String emlDir = getProperty.get("EMAILSENDPATH");//eml存储附件的路径 /nfs/ngsfiles

		//临时文件存储位置
		//String groovyemaildir = "home/www/data/apache-tomcat-9.0.34/webapps/EliteGeneralHttpTask/email/";
		String groovyemaildir = getProperty.get("EMAIL.tempGroovy");

		//String emlFile = "7dfe7acb-dde2-4df6-9c9a-15885c94122a_1675407616104.eml";
		String emlFile="";

		//动态 获取华盛通邮箱地址 'hs.kf@hstong.com'
		String Fromel_Address= KHDBConfig.getParamConfig(eliteBean,"Fromel_Address");

		//token 发送华盛号  接收人
		def sendtaskList = eliteBean.chaxun_sql("select s.Stringfield1 as token,d.sub_doctype,d.DOCUMENTOUT_GUID,d.documentpath from documentout d left join staff s on d.handleby_id=s.STAFF_ID where 1=1 and d.DOCTYPE=2 and  d.status=0 and d.DOCUMENTFROM ='" + Fromel_Address + "' and d.TRIALCOUNTLIMIT>d.TRIALCOUNT and d.CREATEDDATE> DATE_SUB(CURDATE(),INTERVAL 7 DAY) order by d.CREATEDDATE asc", "dataSource");
		log.debug("待处理的邮件发送条数:" + sendtaskList.size());

		if (sendtaskList.size() > 0) {
			String documentpath="";//邮件eml的地址
			String DOCUMENTOUT_GUID="";//唯一id
			String sub_doctype="";//华盛号 接收人
			String token="";//鉴权token

			//初始化 邮件附件图片的存储路径 检查
			def getSelectSQL = eliteBean.chaxun_sql("select  DATE_FORMAT(now(),'%Y-%m-%d') as nowtime", "dataSource");
			String time = getSelectSQL.get(0).get("nowtime");//附件路径临时日期的判断

			//源文件路径  /nfs/ngsfiles/richeditor
			String sourceFilePath=getProperty.get("EMAIL.sourceFilePath");
			//复制文件路径 /nfs/webchatfiles/richeditor
			String targetFolderPath=getProperty.get("EMAIL.targetFolderPath");
			//实际最终公网访问的图片url路径 https://callcenter.hszq8.com/webchat/download?file=
			String webchatrul=getProperty.get("EMAIL.webchatrul");

			//检查邮件富文本附件的路径下文件夹是否存在  每日生成的时间路径
			String FILEURLtime = targetFolderPath +"/"+ time;
			//路径是否存在
			File filefolder = new File(FILEURLtime);
			//如果文件夹不存在则创建
			if (!filefolder.exists() && !filefolder.isDirectory()) {
				log.debug("//不存在");
				filefolder.mkdir();
			} else {
				log.debug("//目录存在");
			}

			//循环捞取的 邮件任务
			for (int i = 0; i < sendtaskList.size(); i++) {
				Map sendtaskMap = sendtaskList.get(i);
				DOCUMENTOUT_GUID = sendtaskMap.get("DOCUMENTOUT_GUID");// 邮件guid
				sub_doctype = sendtaskMap.get("sub_doctype");// 华盛号 接收人
				token = sendtaskMap.get("token");// 鉴权token

				documentpath = sendtaskMap.get("documentpath");// eml地址
				emlFile=documentpath;//  /email/2023_02_03/867ef8c2-2a10-469a-b2e9-81e3c60c5382_1675411609807.eml
				log.debug("DOCUMENTOUT_GUID:" + DOCUMENTOUT_GUID +"	sub_doctype:"+sub_doctype +"	token:"+token +"	documentpath:"+documentpath +"	emlFile:"+emlFile);

				try {
					InputStream inputStream = new FileInputStream(emlDir + emlFile);
					Properties props = new Properties();
					Session session = Session.getDefaultInstance(props, null);
					MimeMessage msg = new MimeMessage(session, inputStream);
					MimeMessageParser parser = new MimeMessageParser(msg).parse();
					/*
					//邮件唯一ID
					String messageId = parser.getMimeMessage().getMessageID();
					log.debug("邮件唯一ID:" + messageId);
					//发件人
					String from = parser.getFrom();
					log.debug("发件人:" + from);

					//密送人列表
					List<Address> bccArray = parser.getBcc();
					log.debug("密送人列表:" + bccArray);
					 */
					//收件人列表
					List<Address> toArray = parser.getTo();
					log.debug("收件人列表:" + toArray);
					String receiver="";//接收人(多个按,隔开） --具体邮箱地址
					if(toArray.size()>0){
						for(int m=0;m<toArray.size();m++){
							receiver=receiver+","+toArray.get(m);
						}
						//截去首位逗号
						receiver=receiver.substring(1);
					}
					log.debug("收件人列表receiver:" + receiver);

					//抄送人列表
					List<Address> ccArray = parser.getCc();
					log.debug("抄送人列表:" + ccArray);
					String ccListStr="";//抄送人（多个按,隔开）--具体邮箱地址
					if(ccArray.size()>0) {
						for(int n=0;n<ccArray.size();n++){
							ccListStr=ccListStr+","+ccArray.get(n);
						}
						//截去首位逗号
						ccListStr=ccListStr.substring(1);
					}
					log.debug("抄送人列表ccListStr:" + ccListStr);

					//邮件发送时间
					String sendDate = dateformat.format(parser.getMimeMessage().getSentDate());
					log.debug("邮件发送时间:" + sendDate);
					//邮件主题
					String subject = parser.getSubject();
					log.debug("邮件主题:" + subject);
					//获取正文
					String html = parser.getHtmlContent();
					//所有文件，包括附件和正文中的图片等文件
					List<DataSource> dataSources = parser.getAttachmentList();
					//获取不到html内容时，则获取非html文本内容
					if (html == null || html.length() == 0) {
						String plain = parser.getPlainContent();
						log.debug("获取非Html正文:" + plain);

					}
					log.debug("获取Html正文:" + html);
					//html=html.replaceAll("https://callcenter-in.hszq8.com/ngs/","https://callcenter.hszq8.com/ngs/");

					//解析获取当前存在多少个附件图片
					List<String> imgList = getImgStrList(html);
					log.debug("imgList:"+imgList);

					//循环处理替换 img图片的url
					for (String img : imgList) {
						log.debug("img:"+img);
						//获取文件名
						String getfilename = img.substring(img.lastIndexOf("/") + 1,img.length());
						//调用复制文件流方法
						boolean type=FileCopy(sourceFilePath,FILEURLtime,getfilename);
						log.debug("上传结果："+type);

						//拼接生成 可通过webchat直接访问的路径url
						String fileimgurl = webchatrul+time+"/"+getfilename;
						log.debug("fileimgurl:"+fileimgurl);
						html=html.replace(img,fileimgurl);//替换HTML中附件图片
					}

					log.debug("获取Html正文-替换url外网前缀:" + html);

					//涉及邮件附件统一塞入处理，先下载到临时文件，后继会删除文件
					ArrayList fileurlarray = new ArrayList();

					for (DataSource dataSource : dataSources) {
						String name = dataSource.getName();
						InputStream is = dataSource.getInputStream();
						FileUtils.copyInputStreamToFile(is, new File(groovyemaildir + name));
						log.debug("邮件附件名称:" + name + " 路径:" + groovyemaildir + name);

						fileurlarray.add(groovyemaildir + name);
					}
					//log.debug("fileurlarray:" + fileurlarray);

					//auto 业务处理
					String client_key="40001";
					String hsNo=sub_doctype;//华盛号
					String title=subject;//邮件标题
					String content=html;//邮件内容
					String sign_time= String.valueOf(Instant.now().getEpochSecond());//验签时间
					log.debug("解析信息-" +  "sign_time: " + sign_time);

					String sign="";//验签
					String url = getProperty.get("HSTURL");
					url = url+"/msg/email/sendemail";

					//鉴权变量
					String appid = getProperty.get("appid");
					String appsecret = getProperty.get("appsecret");

					//sign加密前后
					String signfront = "";
					String signafter = "";

					HashMap<String, String> paramHashMap = new HashMap<String, String>() {
						{
							put("token", token);
							put("sign_time", sign_time);
							put("hsNo", hsNo);
							put("title", title);//邮件标题
							put("content", content);//邮件内容
							if(receiver!=""||receiver!=null){
								put("receiver", receiver);//接收人(多个按,隔开）-为具体的邮箱地址
							}
							if(ccListStr!=""||ccListStr!=null){
								put("ccListStr", ccListStr);//抄送人（多个按,隔开）-为具体的邮箱地址
							}
							//put("receiverValue", "2");//附件
						}
					};

					log.debug("paramHashMap：" + paramHashMap);
					//自然排序 升序参数
					signfront= ThreeDesUtil.sortMap(paramHashMap,appid,appsecret);
					log.debug("sign加密MD5前：" + signfront);
					signafter = Util.getMD5Str(signfront);
					log.debug("sign加密MD5后：" + signafter);

					//验权
					sign=signafter;

					ContentType contentType= ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8);

					Map<String, ContentBody> reqParam = new HashMap<String, ContentBody>();
					reqParam.put("client_key", new StringBody(client_key, contentType));
					reqParam.put("hsNo", new StringBody(hsNo, contentType));
					reqParam.put("title", new StringBody(title, contentType));
					reqParam.put("content", new StringBody(content, contentType));
					reqParam.put("receiver", new StringBody(receiver, contentType));
					reqParam.put("ccListStr", new StringBody(ccListStr, contentType));
					reqParam.put("token", new StringBody(token, contentType));
					reqParam.put("sign_time", new StringBody(sign_time, contentType));
					reqParam.put("sign", new StringBody(sign, contentType));

					//List<MultipartFile> files = new ArrayList<>();//附件
					//处理涉及多附件的模式
					for(int j=0;j<fileurlarray.size();j++){
						// 读取文件
						String filename  = (String) fileurlarray.get(j);
						File file = new File(filename);
						String mimeType = new MimetypesFileTypeMap().getContentType(file);
						log.debug("文件MimeType：" + mimeType);
						//reqParam.put("receiverValue", new FileBody(file, mimeType));
						reqParam.put("receiverValue"+j, new FileBody(file, mimeType));
						//files.add(new FileBody(file, mimeType));
					}
					//reqParam.put("receiverValue", files);

					String httpRes =HttpClientUtil.postFileMultiPart(url, reqParam);
					log.debug("调用发送邮件结果:" + httpRes);

					JSONObject jsonObject = new JSONObject(httpRes);
					String code = GetJV(jsonObject, "code");
					log.debug("接口返回code：" + code);
					//api接口 成功
					if (code == "00000") {
						eliteBean.update("update documentout set STATUS=1,TRIALCOUNT=TRIALCOUNT+1,MODIFIEDDATE=NOW(),MODIFIEDBY='SELITE',LASTTRYDATETIME=now() where DOCUMENTOUT_GUID='" + DOCUMENTOUT_GUID + "' ", "dataSource");
					}else{
						eliteBean.update("update documentout set STATUS=5,TRIALCOUNT=TRIALCOUNT+1,MODIFIEDDATE=NOW(),MODIFIEDBY='SELITE' where DOCUMENTOUT_GUID='" + DOCUMENTOUT_GUID + "' ", "dataSource");
					}

					for(int j=0;j<fileurlarray.size();j++){
						String deletename  = (String) fileurlarray.get(j);
						//log.debug("deletename:" + deletename );
						//删除文件
						deleteFile(deletename);
					}

				} catch (Exception e) {
					e.printStackTrace();
				}

			}
		}else{
			log.debug("系统检查，无邮件发送任务！");
		}
	}

	//删除文件
	public static boolean deleteFile(String fileName) {
		File file = new File(fileName);
		// 如果文件路径只有单个文件
		if (file.exists() && file.isFile()) {
			if (file.delete()) {
				log.debug("删除文件" + fileName + "成功！");
				return true;
			} else {
				log.debug("删除文件" + fileName + "失败！");
				return false;
			}
		} else {
			log.debug(fileName + "不存在！");
			return false;
		}
	}

	/**
	 * 提取HTML字符串中的img列表
	 * @param htmlStr 要处理的html字符串
	 * @return
	 */
	private static List<String> getImgStrList(String htmlStr) {
		List<String> list = new ArrayList<>();
		String img = "";
		Pattern p_image;
		Matcher m_image;
		String regEx_img = "<img.*src\\s*=\\s*(.*?)[^>]*?>";
		p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
		m_image = p_image.matcher(htmlStr);
		while (m_image.find()) {
			img = m_image.group();
			Matcher m = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(img);
			while (m.find()) {
				list.add(handleSrc(m.group(1)));
			}
		}
		return list;
	}

	/**
	 * 去除src路径中的前后单引号
	 * @param src 图片的src路径
	 * @return
	 */
	private static String handleSrc(String src) {
		if (src != null) {
			if (src.startsWith("'")) {
				return src.substring(1, src.length());
			}
			if (src.endsWith("'")) {
				return src.substring(0, src.length());
			}

		}
		return src;
	}

	// 同服务器下 文件附件的复制
	private static boolean FileCopy(String sourceFilePath,String targetFolderPath,String filename) {
		// 源文件路径 sourceFilePath 		// 目标文件夹路径 targetFolderPath
		boolean type=true;
		// 创建输入流和输出流
		try {
			InputStream inputStream = new FileInputStream(sourceFilePath+ "/" + filename);
			 OutputStream outputStream = new FileOutputStream(targetFolderPath + "/" + filename)

			// 缓冲区大小，用于提高读写效率
			byte[] buffer = new byte[1024];
			int length;

			// 读取输入流中的内容，并写入输出流中
			while ((length = inputStream.read(buffer)) > 0) {
				outputStream.write(buffer, 0, length);
			}
			log.debug("文件复制完成！");
			type=true;
		} catch (IOException e) {
			//e.printStackTrace();
			type=false;
		}
		return type;
	}

	// 解析Json值
	public static String GetJV(JSONObject inJson, String getKey) {
		String Rev_Value = null;
		try {
			Rev_Value = inJson.getString(getKey);
		} catch (Exception e) {
			try {
				Rev_Value = String.valueOf(inJson.getInt(getKey));
			} catch (Exception e1) {
				try {
					Rev_Value = String.valueOf(inJson.getJSONArray(getKey));
				} catch (Exception e2) {
					try {
						Rev_Value = String.valueOf(inJson.getJSONObject(getKey));
					} catch (Exception e3) {
						Rev_Value = "";
					}
				}
			}
		} finally {
			if (Rev_Value == null || Rev_Value.equals("null") || Rev_Value.length() <= 0) {
				Rev_Value = "";
			} else {
			}
		}
		log.debug("解析-k=" + getKey + " v=" + Rev_Value);
		return Rev_Value;

	}
}

